#include "lwip/api.h"
#include "lwip/sys.h"
#include <lwip/sockets.h>
#include <sys/cdefs.h>

#define IPERF_PORT 5001
#define IPERF_BUFSZ (1 * 1024)

_Noreturn void iperf_server(void *thread_param) {
    struct netconn *conn;
    struct netconn *newconn;
    err_t err;
    void *recv_data;
    lwip_socket_thread_init();

    conn = netconn_new(NETCONN_TCP);
    netconn_bind(conn, IP_ADDR_ANY, 5001);

    LWIP_ERROR("tcpecho: invalid conn", (conn != NULL), return;);

    /* Tell connection to go into listening mode. */
    netconn_listen(conn);

    while (1) {

        /* Grab new connection. */
        err = netconn_accept(conn, &newconn);
        int flag = 1;
        //        setsockopt(newconn->socket, IPPROTO_TCP, TCP_NODELAY, (void *)
        //        &flag, sizeof(int));
        log_debug("accepted new connection\n");
        /* Process the new connection. */
        if (err == ERR_OK) {
            struct netbuf *buf;
            //      void *data;
            u16_t len;
            while (1) {
                err = netconn_recv(newconn, &buf);
                if (err != ERR_OK) {
                    log_debug("netconn_recv failed: %d\n", err);
                    break;
                }
//        log_debug("Recved\n");
                do {
                    err_t res = netbuf_data(buf, &recv_data, &len);
                    if (res != ERR_OK) {
                        log_debug("netbuf_data failed\n");
                    }
//          log_debug("len:%d\n", len);
                    //   netconn_write(newconn, recv_data, len, NETCONN_COPY);
                } while (netbuf_next(buf) >= 0);
                netbuf_delete(buf);
            }
            log_debug("Got EOF, looping\n");
            /* Close connection and discard connection identifier. */
            netconn_close(newconn);
            netconn_delete(newconn);
        }
    }
}

void iperf_server_netconn_init(void) {
    sys_thread_new("iperf_netserver", iperf_server, NULL, 1024, 0);
}
